#if UNITY_EDITOR

using System.IO;
using Dou.GPU;
using MessagePack;
using Unity.Mathematics;
using UnityEditor;
using UnityEngine;
using Random = Unity.Mathematics.Random;

namespace Simple.GPUInstancing.SampleTest
{
    /// <summary>
    /// GPU 蒙皮动画测试
    /// </summary>
    public class SkinnedMeshScript : MonoBehaviour
    {
        public int count = 100000;
        public Mesh mesh;
        public Material material;
        public Object animDataFile;
        public string[] animNames = new string[0];

        private int _batchId;

        private int[] _testUIDs = new[] {1, 2, 3};
        private GPUAnimation[] _testAnim = new GPUAnimation[3];

        void Start()
        {
            var animData =
                MessagePackSerializer.Deserialize<GPUAnimData>(
                    File.ReadAllBytes(AssetDatabase.GetAssetPath(animDataFile)));
            _batchId = GPUSkinnedMeshMgr.instance.RegisterAnimation(mesh, material, animData);

            var col = (int) math.ceil(math.sqrt(count));
            var random = Random.CreateFromIndex(0);

            for (int i = 0; i < count; i++)
            {
                // var uid = GPUSkinnedMeshMgr.instance.CreateAnimation(_batchId);
                // var animation = GPUSkinnedMeshMgr.instance.GetAnimation(uid);
                //
                // animation.data.position = new float3((i % col) * 2f, 0, math.floor(i / col) * 2);
                // animation.data.rotation = quaternion.Euler(0, random.NextFloat(0f, 360f), 0);
                // var s = random.NextFloat(0.8f, 1.2f);
                // animation.data.scale = new float3(s, s, s);
                //
                // animation.Play(animNames[UnityEngine.Random.Range(0, animNames.Length)]);

                var s = random.NextFloat(0.8f, 1.2f);
                var uid = GPUSkinnedMeshMgr.instance.CreateAnimation(_batchId,
                    new float3((i % col) * 2f, 0, math.floor(i / col) * 2),
                    quaternion.Euler(0, random.NextFloat(0f, 360f), 0),
                    new float3(s, s, s));

                GPUSkinnedMeshMgr.instance.PlayAnimation(uid, animNames[UnityEngine.Random.Range(0, animNames.Length)]);
            }

            for (int i = 0; i < _testUIDs.Length; i++)
            {
                _testAnim[i] = GPUSkinnedMeshMgr.instance.GetAnimation(_testUIDs[i]);
            }
        }

        void Update()
        {
            GPUSkinnedMeshMgr.instance.Update(Time.deltaTime);
            GPUInstancingMgr.instance.Draw();
        }

        public void ReplaceAnim_1()
        {
            foreach (var uid in _testUIDs)
            {
                GPUSkinnedMeshMgr.instance.PlayAnimation(uid, animNames[UnityEngine.Random.Range(0, animNames.Length)]);
            }
        }

        public void ReplaceAnim_2()
        {
            foreach (var animation in _testAnim)
            {
                animation.Play(animNames[UnityEngine.Random.Range(0, animNames.Length)]);
            }
        }

        public void SetSpeed()
        {
            foreach (var uid in _testUIDs)
            {
                GPUSkinnedMeshMgr.instance.SetTimeScale(uid, 1.5f);
            }
        }

        public void Pause()
        {
            foreach (var uid in _testUIDs)
            {
                GPUSkinnedMeshMgr.instance.PauseAnimation(uid);
            }
        }

        public void Resume()
        {
            foreach (var uid in _testUIDs)
            {
                GPUSkinnedMeshMgr.instance.ResumeAnimation(uid);
            }
        }

        public void SetTrans()
        {
            foreach (var uid in _testUIDs)
            {
                GPUSkinnedMeshMgr.instance.SetScale(uid, 2);
            }
            foreach (var animation in _testAnim)
            {
                animation.data.position += new float3(0, 1, 0);
                animation.data.rotation = math.mul(animation.data.rotation, quaternion.Euler(0, 45, 0));
            }
        }
    }
}

#endif